<?php
/**
 * @Author: Ron Chen
 * @Date:   2017-04-09 16:04:53
 * @Last Modified by:   Ron Chen
 * @Last Modified time: 2017-07-18 22:46:01
 */

namespace app\services;

use Yii;
use yii\web\Response;

use app\models\InsurancePolicy;
use app\models\InsurancePlan;
use app\models\InsurancePolicyHolder;
use app\models\InsurancePolicyInsured;

/**
 * 保单相关服务
 */
class PolicyServices
{
    // 测试地址
    // public $user_id = 'AC000039';//'BA100162_01';
    // public $password = 'password';//'Z43Yz!b2';
    // public $api_server = 'https://test.allianz.cn/IG_ePolicy/OTI-azcn-policy'; // test/eservice
    // public $password_server = 'https://test.allianz.cn/IG_ePolicy/EncryptPassword'; // test/eservice

    // 正式地址
    public $user_id = 'BA100162_01';
    public $main_user_id = 'BA100162';

    public $password = 'Z43Yz!b2';
    public $api_server = 'https://eservice.allianz.cn/IG_ePolicy/OTI-azcn-policy'; // test/eservice
    public $password_server = 'https://eservice.allianz.cn/IG_ePolicy/EncryptPassword'; // test/eservice

    public $api_method = 'post';

    const PREMIUM_CAL_NORMAIL = 1;
    const PREMIUM_CAL_DOUBLE = 2;
    const PREMIUM_CAL_FAMILY = 3;

    public static $premiumCalType = [
        self::PREMIUM_CAL_NORMAIL => "普通",
        self::PREMIUM_CAL_DOUBLE => "双人",
        self::PREMIUM_CAL_FAMILY => "家庭",
    ];

    // 投保人类型: 个人、企业或者机构
    const POLICY_HOLDER_TYPE_INDIVIDUAL = 'I';
    const POLICY_HOLDER_TYPE_COMPANY = 'C';


    /**
     * 添加保单信息
     */
    public function addPolicyOrder($order_id)
    {
        $xml = $this->_getXML('0002');
        $body = $xml->getElementsByTagName('Body') [0];

        $obj = array();
        // 获取保单的基本信息
        $policy_info = InsurancePolicy::findOne($order_id);
        if (!$policy_info) {
            return false;
        }

        $obj = [
            "policy_id" => $order_id,
            "plan_code" => $policy_info->plan_code,
            "start_date" => empty($policy_info->issue_date) ? date("YmdHis") : date('YmdHis', strtotime($policy_info->issue_date)),
            "effect_date" => empty($policy_info->effect_date) ? date("YmdHis") : date('YmdHis', strtotime($policy_info->effect_date)),
            "expire_date" => empty($policy_info->expire_date) ? date("YmdHis") : date('YmdHis', strtotime($policy_info->expire_date)),
            "destination" => $policy_info->destination,
            "PremiumCalType" => self::PREMIUM_CAL_NORMAIL,
            "TotalPremium" => $policy_info->premium_total,
        ];

        // 添加被保险人信息
        $policy_insured = InsurancePolicyInsured::find()->where(['policy_id' => $order_id])->limit(10)->all();
        if ($policy_insured) {
            $insured_arr = [];
            foreach ($policy_insured as $row) {

                $temp_insured_type = empty($row->insured_type) ? 1 : $row->insured_type;
                $temp_age = $this->_birthday($row->birth_date);
                if ($temp_age && $temp_age < 18) {
                    $temp_insured_type = 2;
                }

                $insured_arr[] = [
                    'InsuredId' => $row->id,
                    'InsuredName' => $row->insured_name,
                    'InsuredType' => $temp_insured_type,
                    'IdType' => $row->id_type,
                    'IdNumber' => $row->id_number,
                    'BirthDate' => date('YmdHis', strtotime($row->birth_date)),
                    'Mobile' => $row->mobile,
                    'Email' => $row->email,
                    'Gender' => $row->gender,
                    'BeneficialType' => $row->benificial_type,
                    'OccupationCode' => $row->occupation_code,
                    'PolicyholderInsuredRelation' => $row->policy_holder_relation,
                ];
            }
            $obj['insured'] = $insured_arr;
        } else {
            $obj['insured'] = [];
        }

        // policy
        $policy = $xml->createElement('Policy', '');
        $policy->appendChild($xml->createElement('AgencyPolicyRef', $obj['policy_id']));
        $policy->appendChild($xml->createElement('PlanCode', $obj['plan_code']));
        $policy->appendChild($xml->createElement('IssueDate', $obj['start_date']));
        $policy->appendChild($xml->createElement('EffectiveDate', $obj['effect_date']));
        $policy->appendChild($xml->createElement('ExpireDate', $obj['expire_date']));
        $policy->appendChild($xml->createElement('Destination', $obj['destination']));
        $policy->appendChild($xml->createElement('GroupSize', count($obj['insured'])));
        $policy->appendChild($xml->createElement('Remark', $obj['plan_code']));
        $policy->appendChild($xml->createElement('PremiumCalType', $obj['PremiumCalType']));
        $policy->appendChild($xml->createElement('TotalPremium', $obj['TotalPremium']));
        $body->appendChild($policy);
        // agency
        $agency = $xml->createElement('Agency', '');
        $agency->appendChild($xml->createElement('AgencyCode', $this->main_user_id));
        $body->appendChild($agency);

        // 获取投保人信息
        $policyHolder = InsurancePolicyHolder::findOne($order_id);
        $holder_obj = [
            "PolicyHolderName" => self::POLICY_HOLDER_TYPE_INDIVIDUAL,
            "PHIdType" => '',
            "PHIdNumber" => '',
            "PHBirthDate" => '',
            "PHTelephone" => '',
            "PHAddress" => '',
            "PHEmail" => '',
            "PHPostCode" => '',
            "ReqFaPiao" => 0,
            "ReqMail" => 0,
            "MailType" => 1,
            "ReqElecFaPiao" => N,
            "InvoiceTitle" => '',
        ];
        if ($policyHolder) {
            $holder_obj = [
                "PolicyHolderType" => !empty($policyHolder->policy_holder_type) ? $policyHolder->policy_holder_type : self::POLICY_HOLDER_TYPE_INDIVIDUAL,
                "PolicyHolderName" => $policyHolder->policy_holder_name,
                "PHIdType" => $policyHolder->id_type,
                "PHIdNumber" => $policyHolder->id_number,
                "PHBirthDate" => date('YmdHis', strtotime($policyHolder->birthday)),
                "PHTelephone" => $policyHolder->telephone,
                "PHAddress" => $policyHolder->address,
                "PHEmail" => $policyHolder->email,
                "PHPostCode" => '',
                "ReqFaPiao" => 0,
                "ReqMail" => 0,
                "MailType" => 1,
                "ReqElecFaPiao" => N,
                "InvoiceTitle" => '',
            ];
        }

        // policy_holder
        $policy_holder = $xml->createElement('PolicyHolder', '');
        $policy_holder->appendChild($xml->createElement('PolicyHolderType', $holder_obj['PolicyHolderType']));
        $policy_holder->appendChild($xml->createElement('PolicyHolderName', $holder_obj['PolicyHolderName']));
        $policy_holder->appendChild($xml->createElement('PHIdType', $holder_obj['PHIdType']));
        $policy_holder->appendChild($xml->createElement('PHIdNumber', $holder_obj['PHIdNumber']));
        $policy_holder->appendChild($xml->createElement('PHBirthDate', $holder_obj['PHBirthDate']));
        $policy_holder->appendChild($xml->createElement('PHTelephone', $holder_obj['PHBirthDate']));
        $policy_holder->appendChild($xml->createElement('PHAddress', $holder_obj['PHAddress']));
        $policy_holder->appendChild($xml->createElement('PHPostCode', $holder_obj['PHPostCode']));
        $policy_holder->appendChild($xml->createElement('PHEmail', $holder_obj['PHEmail']));
        $policy_holder->appendChild($xml->createElement('ReqFaPiao', $holder_obj['ReqFaPiao']));
        $policy_holder->appendChild($xml->createElement('ReqMail', $holder_obj['ReqMail']));
        $policy_holder->appendChild($xml->createElement('MailType', $holder_obj['MailType']));
        $policy_holder->appendChild($xml->createElement('ReqElecFaPiao', $holder_obj['ReqElecFaPiao']));
        $policy_holder->appendChild($xml->createElement('InvoiceTitle', $holder_obj['InvoiceTitle']));

        $body->appendChild($policy_holder);

        // insured
        if (is_array($obj['insured']) && count($obj['insured']) > 0) {
            $insured_list = $xml->createElement('InsuredList', '');
            foreach ($obj['insured'] as $m) {
                $xml_insured = $xml->createElement('Insured', '');
                $xml_insured->appendChild($xml->createElement('InsuredId', $m['InsuredId']));
                $xml_insured->appendChild($xml->createElement('InsuredName', $m['InsuredName']));
                $xml_insured->appendChild($xml->createElement('InsuredType', $m['InsuredType']));
                $xml_insured->appendChild($xml->createElement('IdType', $m['IdType']));
                $xml_insured->appendChild($xml->createElement('IdNumber', $m['IdNumber']));
                $xml_insured->appendChild($xml->createElement('BirthDate', $m['BirthDate']));
                $xml_insured->appendChild($xml->createElement('Mobile', $m['Mobile']));
                $xml_insured->appendChild($xml->createElement('Email', $m['Email']));
                $xml_insured->appendChild($xml->createElement('Gender', $m['Gender']));
                $xml_insured->appendChild($xml->createElement('BeneficialType', $m['BeneficialType']));
                $xml_insured->appendChild($xml->createElement('BeneficiaryList', $m['BeneficiaryList']));
                $xml_insured->appendChild($xml->createElement('EmergencyContact', $m['EmergencyContact']));
                $xml_insured->appendChild($xml->createElement('OccupationCode', $m['OccupationCode']));
                $xml_insured->appendChild($xml->createElement('PolicyholderInsuredRelation', $m['PolicyholderInsuredRelation']));
                $insured_list->appendChild($xml_insured);
            }
            $body->appendChild($insured_list);
        }
        // else{
        // 	$xml_insured = $xml->createElement ( 'Insured', '' );
        // 	$xml_insured->appendChild($xml->createElement('InsuredId',''));
        // 	$xml_insured->appendChild($xml->createElement('InsuredName',''));
        // 	$xml_insured->appendChild($xml->createElement('InsuredType',1));
        // 	$xml_insured->appendChild($xml->createElement('IdType',1));
        // 	$xml_insured->appendChild($xml->createElement('IdNumber',''));
        // 	$xml_insured->appendChild($xml->createElement('BirthDate',''));
        // 	$xml_insured->appendChild($xml->createElement('Mobile',''));
        // 	$xml_insured->appendChild($xml->createElement('Email',''));
        // 	$xml_insured->appendChild($xml->createElement('Gender',''));
        // 	$xml_insured->appendChild($xml->createElement('BeneficialType',''));
        // 	$xml_insured->appendChild($xml->createElement('BeneficiaryList',''));
        // 	$xml_insured->appendChild($xml->createElement('EmergencyContact',''));
        // 	$xml_insured->appendChild($xml->createElement('OccupationCode',''));
        // 	$xml_insured->appendChild($xml->createElement('PolicyholderInsuredRelation',''));
        // 	$insured_list->appendChild ( $xml_insured );
        // }
        return $this->_curlPost($this->api_server, $xml->saveXML());

        // return $xml->saveXML();

    }

    /**
     * 打印保单信息
     */
    public function printOrder($order_id)
    {
        $xml = $this->_getXML('0006');
        $body = $xml->getElementsByTagName('Body') [0];

        $obj = array();
        // 获取保单的基本信息
        $policy_info = InsurancePolicy::findOne($order_id);
        if (!$policy_info) {
            return false;
        }

        $policy = $xml->createElement('Policy', '');
        $policy->appendChild($xml->createElement('PolicyRef', $policy_info->policy_id));
        $policy->appendChild($xml->createElement('Format', 'F01'));
        $body->appendChild($policy);

        return $this->_curlPost($this->api_server, $xml->saveXML());
    }


    public function getResponse($data)
    {
        return $this->_curlPost($this->api_server, $data);
    }

    // 获取XML头
    private function _getXML($type)
    {
        $xml = new \DOMDocument ('1.0', 'utf-8');

        $packet = $xml->createElement('Packet');
        $xml->appendChild($packet);
        $packet->setAttribute('type', 'REQUEST');
        $packet->setAttribute('version', '1.0');

        $head = $xml->createElement('Head');
        $packet->appendChild($head);

        $body = $xml->createElement('Body');
        $packet->appendChild($body);

        $request_id = $xml->createElement('RequestID', $this->user_id . $type . $this->_getTimeStamp());
        $head->appendChild($request_id);

        $request_type = $xml->createElement('RequestType', $type);
        $head->appendChild($request_type);

        $request_user = $xml->createElement('User', $this->user_id);
        $head->appendChild($request_user);

        $request_password = $xml->createElement('Password', $this->_getEncryptPassword());
        $head->appendChild($request_password);

        return $xml;
    }

    // 获取时间戳
    private function _getTimeStamp()
    {
        list ($msec, $sec) = explode(' ', microtime());
        return ( float )sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }

    //判断当前年龄
    private function _birthday($birthday)
    {
        $age = strtotime($birthday);
        if ($age === false) {
            return 0;
        }
        list($y1, $m1, $d1) = explode("-", date("Y-m-d", $age));
        $now = strtotime("now");
        list($y2, $m2, $d2) = explode("-", date("Y-m-d", $now));
        $age = $y2 - $y1;
        if ((int)($m2 . $d2) < (int)($m1 . $d1))
            $age -= 1;
        return $age;
    }

    /**
     * 密码二次加密
     */
    private function _getEncryptPassword()
    {
        return $this->_curlPost($this->password_server, 'Password=' . $this->password);
    }

    private function _curlPost($url, $data)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_PORT, 443);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

        $ret = curl_exec($ch);
        $err = curl_error($ch);

        curl_close($ch);
        return ( string )$ret;
    }

    //根据保单号获取保单信息
    public function getPolicyInfo($policy_id)
    {
        $insurancePolicy = InsurancePolicy::find()
            ->from(InsurancePolicy::tableName() . ' as a')
            ->leftjoin(InsurancePlan::tableName() . ' as b', 'a.plan_code = b.plan_code')
            ->where(['policy_id' => $policy_id])
            ->asArray()
            ->select('a.id,a.insured_amount,b.project_code')
            ->limit(1)->one();
        $insurancePolicy['product'] = InsurancePolicy::$productType[$insurancePolicy['project_code']];
        $insurancePolicy['order_info'] = InsurancePolicy::POLICY_DETAILS . $insurancePolicy['id'] . '?key=al';
        $insurancePolicy['return_url'] = InsurancePolicy::$returnUrl[$insurancePolicy['project_code']];
        $insurancePolicy['share'] = file_get_contents(InsurancePolicy::SHARE_API);
        return $insurancePolicy;
    }
}